﻿global using Devonline.AspNetCore;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

namespace Devonline.Database.TimeSeries.InfluxDB;

public static class ServiceExtensions
{
    /// <summary>
    /// 注册数据库上下文
    /// </summary>
    /// <param name="services">依赖注入服务容器</param>
    /// <param name="endpoint">InfluxDB 数据库配置项</param>
    /// <param name="serviceLifetime">InfluxDBService 生命周期</param>
    /// <returns></returns>
    public static IServiceCollection AddKeyedInfluxDBService(this IServiceCollection services, IInfluxDBEndpoint endpoint, ServiceLifetime serviceLifetime = ServiceLifetime.Scoped)
    {
        services.AddSingleton<IInfluxDBEndpoint>(endpoint);
        Func<IServiceProvider, object?, InfluxDBService> implementationFactory = (serviceProvider, _) => new InfluxDBService(serviceProvider.GetRequiredService<ILogger<InfluxDBService>>(), endpoint);
        switch (serviceLifetime)
        {
            case ServiceLifetime.Transient:
                services.AddKeyedTransient<ITimeSeriesService, InfluxDBService>(endpoint.Name, implementationFactory);
                break;
            case ServiceLifetime.Singleton:
                services.AddKeyedSingleton<ITimeSeriesService, InfluxDBService>(endpoint.Name, implementationFactory);
                break;
            case ServiceLifetime.Scoped:
            default:
                services.AddKeyedScoped<ITimeSeriesService, InfluxDBService>(endpoint.Name, implementationFactory);
                break;
        }

        return services;
    }
    /// <summary>
    /// 注册数据库上下文
    /// </summary>
    /// <param name="services">依赖注入服务容器</param>
    /// <param name="endpoint">InfluxDB 数据库配置项</param>
    /// <param name="serviceLifetime">InfluxDBDataService 生命周期</param>
    /// <returns></returns>
    public static IServiceCollection AddKeyedInfluxDBDataService(this IServiceCollection services, IInfluxDBEndpoint endpoint, ServiceLifetime serviceLifetime = ServiceLifetime.Scoped)
    {
        services.AddSingleton<IInfluxDBEndpoint>(endpoint);
        Func<IServiceProvider, object?, InfluxDBDataService> implementationFactory = (serviceProvider, _) =>
        {
            var logger = serviceProvider.GetRequiredService<ILogger<InfluxDBDataService>>();
            var httpContextAccessor = serviceProvider.GetRequiredService<IHttpContextAccessor>();
            var httpSetting = serviceProvider.GetRequiredService<HttpSetting>();
            return new InfluxDBDataService(logger, endpoint, httpContextAccessor, httpSetting);
        };
        switch (serviceLifetime)
        {
            case ServiceLifetime.Transient:
                services.AddKeyedTransient<ITimeSeriesDataService, InfluxDBDataService>(endpoint.Name, implementationFactory);
                break;
            case ServiceLifetime.Singleton:
                services.AddKeyedSingleton<ITimeSeriesDataService, InfluxDBDataService>(endpoint.Name, implementationFactory);
                break;
            case ServiceLifetime.Scoped:
            default:
                services.AddKeyedScoped<ITimeSeriesDataService, InfluxDBDataService>(endpoint.Name, implementationFactory);
                break;
        }

        return services;
    }

    /// <summary>
    /// 注册数据库上下文
    /// </summary>
    /// <param name="services">依赖注入服务容器</param>
    /// <param name="endpoint">InfluxDB 数据库配置项</param>
    /// <param name="serviceLifetime">InfluxDBService 生命周期</param>
    /// <returns></returns>
    public static IServiceCollection AddInfluxDBService(this IServiceCollection services, IInfluxDBEndpoint endpoint, ServiceLifetime serviceLifetime = ServiceLifetime.Scoped)
    {
        services.AddSingleton<IInfluxDBEndpoint>(endpoint);
        switch (serviceLifetime)
        {
            case ServiceLifetime.Transient:
                services.AddTransient<ITimeSeriesService, InfluxDBService>();
                break;
            case ServiceLifetime.Singleton:
                services.AddSingleton<ITimeSeriesService, InfluxDBService>();
                break;
            case ServiceLifetime.Scoped:
            default:
                services.AddScoped<ITimeSeriesService, InfluxDBService>();
                break;
        }

        return services;
    }
    /// <summary>
    /// 注册数据库上下文
    /// </summary>
    /// <param name="services">依赖注入服务容器</param>
    /// <param name="endpoint">InfluxDB 数据库配置项</param>
    /// <param name="serviceLifetime">InfluxDBDataService 生命周期</param>
    /// <returns></returns>
    public static IServiceCollection AddInfluxDBDataService(this IServiceCollection services, IInfluxDBEndpoint endpoint, ServiceLifetime serviceLifetime = ServiceLifetime.Scoped)
    {
        services.AddSingleton<IInfluxDBEndpoint>(endpoint);
        switch (serviceLifetime)
        {
            case ServiceLifetime.Transient:
                services.AddTransient<ITimeSeriesDataService, InfluxDBDataService>();
                break;
            case ServiceLifetime.Singleton:
                services.AddSingleton<ITimeSeriesDataService, InfluxDBDataService>();
                break;
            case ServiceLifetime.Scoped:
            default:
                services.AddScoped<ITimeSeriesDataService, InfluxDBDataService>();
                break;
        }

        return services;
    }
}